package my.mybatis.common;

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.ToString;
import my.mybatis.common.util.OperatorConventor;
import my.mybatis.common.util.QueryValueConventor;
import my.mybatis.common.util.Underline2Camel;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.util.StringUtils;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

/**
 * @Author:wangbin.
 * @Description.
 * @Date:Created in 9:10 2017/9/18.
 * @Modified By:
 */
@ToString
@ApiModel(description = "特殊查询通用封装")
public class QueryParams<T> implements Serializable{
    private static final long serialVersionUID = 5861326765039514231L;

    @ApiModelProperty(value = "查询的对象参数")
    private T param;
    // 排序参数，可以设置字段的顺序，值越小越优先
	@ApiModelProperty(value = "排序字段")
    private List<OrderParam> orderParams = new ArrayList<OrderParam>();;
    // 查询参数
	@ApiModelProperty(value = "多条件封装")
    private List<QueryParam> queryParams = new ArrayList<QueryParam>();
    // 排序字符串，可以是多个字段的排序，也可以通过set orderParams来进行自动映射
    private String orderClause;
    // 简单分页语句时候用
    private String limitClause;
    private LimitParam limitParam;

    public QueryParams(T param) {
        this.param = param;
    }

    public T getParam() {
        return param;
    }

    public void setParam(T param) {
        this.param = param;
    }

    public List<OrderParam> getOrderParams() {
        return orderParams;
    }

    public void setOrderParams(List<OrderParam> orderParams) {
        // 此处做排序是为了排序语句的解析，排序字段有先后顺序
        if(!CollectionUtils.isEmpty(orderParams))
        {
            Collections.sort(orderParams, new Comparator<OrderParam>() {
                public int compare(OrderParam o1, OrderParam o2) {
                    return o1.getOrderIndex() - o2.getOrderIndex();
                }
            });
            this.orderParams = orderParams;
            orderClause = " ORDER BY ";
            for (int i = 0; i < orderParams.size(); i++)
                orderClause += Underline2Camel.camel2Underline(orderParams.get(i).getOrderBy()) + " " + orderParams.get(i).getAscOrDesc() + ",";
            orderClause = orderClause.substring(0,orderClause.length()-1);
        }
    }

    public void setLimitParam(LimitParam limitParam) {
        this.limitParam = limitParam;
        this.limitClause = limitParam.getLimitSql();
    }

    public List<QueryParam> getQueryParams() {
        return queryParams;
    }

    public void setQueryParams(List<QueryParam> searchParams) {
        if(!CollectionUtils.isEmpty(searchParams))
            this.queryParams.addAll(searchParams);
        if(!CollectionUtils.isEmpty(this.queryParams))
        {
            List<QueryParam> dateEqlDealList = new ArrayList<QueryParam>();
            for (QueryParam queryParam : this.queryParams)
                if(!QueryValueConventor.convertQueryParam(param.getClass(), queryParam,dateEqlDealList))
                    dateEqlDealList.add(queryParam);
            // 处理日期等于条件的操作
            for (QueryParam queryParam : dateEqlDealList)
                queryParamObjectToSqlParam(queryParam);
            // 从新把处理后的值赋给searchParams
            this.queryParams = dateEqlDealList;
        }
    }

    /**
     * 讲查询参数映射成为数据库的查询参数
     * @param queryParam
     */
    private void queryParamObjectToSqlParam(QueryParam queryParam)
    {
        queryParam.setOperator(OperatorConventor.get(queryParam.getOperator().toLowerCase()));
        if(!queryParam.isNoValue())
        {
            if(queryParam.isLike())
                queryParam.setValue("%" + QueryValueConventor.get(param.getClass(), queryParam.getKey(), queryParam.getValue()) + "%");
            else if(queryParam.isListValue())
                queryParam.setValue(QueryValueConventor.get(queryParam.getValue()));
            else
                queryParam.setValue(QueryValueConventor.get(param.getClass(), queryParam.getKey(), queryParam.getValue()));
        }
        queryParam.setKey(Underline2Camel.camel2Underline(queryParam.getKey()));
    }

    public void addQueryParam(QueryParam queryParam)
    {
        queryParamObjectToSqlParam(queryParam);
        this.queryParams.add(queryParam);
    }

    public void addOrderParam(OrderParam orderParam)
    {
        this.orderParams.add(orderParam);
        if(StringUtils.isEmpty(orderClause))
        {
            orderClause = " ORDER BY ";
            orderClause += Underline2Camel.camel2Underline(orderParam.getOrderBy()) + " " + orderParam.getAscOrDesc() + " ";
        }
        else
            orderClause += "," + Underline2Camel.camel2Underline(orderParam.getOrderBy()) + " " + orderParam.getAscOrDesc() + " ";

    }
}
